﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using DeepZoomPivotConstructor.VisualCacheInterfaces;
using DeepZoomPivotConstructor.VisualLib;
using System.ComponentModel.Composition;
using System.Threading.Tasks;
using DeepZoomPivotConstructor.VisualCacheXMLDirectory;

namespace t_VisualCache
{
    /// <summary>
    /// Test out the visual cache db guy.
    /// </summary>
    [TestClass]
    public class t_VisualCacheDirectoryDB
    {
        public t_VisualCacheDirectoryDB()
        {
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        [TestInitialize]
        public void TestInit()
        {
            t_TestingLibrary.Utilities.MyClassInit();
        }

        [TestCleanup]
        public void TestDone()
        {
            t_TestingLibrary.Utilities.MyClassDone();
        }

        [TestMethod]
        public void TestDBSimpleCreation()
        {
            DirectoryInfo dbdir = new DirectoryInfo("TestDBSimpleCreation");

            VisualCacheDirectoryDB db = new VisualCacheDirectoryDB(dbdir);
        }

        [TestMethod]
        public void LookForSomethingNotThere()
        {
            DirectoryInfo dbdir = new DirectoryInfo("LookForSomethingNotThere");
            VisualCacheDirectoryDB db = new VisualCacheDirectoryDB(dbdir);

            Assert.IsNull(db.FindHit(1234), "Empty DB should have no hits!");
        }

        [TestMethod]
        public void StoreVCacheDB()
        {
            CacheDBInfo info = new CacheDBInfo();
            info.DZXMLFile = new FileInfo("junk.xml");

            info.ComposeInfo = new ComposableInfo();
            Uri theObj = new Uri ("http://www.nytimes.com");
            info.ComposeInfo.Hash = theObj.AbsolutePath.GetHashCode();
            info.ComposeInfo.Height = 1.0;
            info.ComposeInfo.MetaData = DateTime.Now;
            info.ComposeInfo.RenderItemFullType = typeof(t_VisualCacheDirectoryDB).ToString();
            info.ComposeInfo.RenderObject = theObj;
            info.ComposeInfo.Width = 2.0;

            DirectoryInfo dbdir = new DirectoryInfo("StoreVCacheDB");
            VisualCacheDirectoryDB db = new VisualCacheDirectoryDB(dbdir);
            db.Save(info);

            Assert.IsNotNull(db.FindHit(info.ComposeInfo.Hash), "Wrong number of items found in db");

            CacheDBInfo infoRet = db.FindHit(info.ComposeInfo.Hash);
            Assert.AreEqual(1.0, infoRet.ComposeInfo.Height, "Height came back incorrect");

            Assert.IsNull(db.FindHit(124443), "Shoud find bogus number of items for bogus id");
        }

        [TestMethod]
        public void CorruptCacheDBEntry()
        {
            CacheDBInfo info = new CacheDBInfo();
            info.DZXMLFile = new FileInfo("junk.xml");

            info.ComposeInfo = new ComposableInfo();
            Uri theObj = new Uri("http://www.nytimes.com");
            info.ComposeInfo.Hash = theObj.AbsolutePath.GetHashCode();
            info.ComposeInfo.Height = 1.0;
            info.ComposeInfo.MetaData = DateTime.Now;
            info.ComposeInfo.RenderItemFullType = typeof(t_VisualCacheDirectoryDB).ToString();
            info.ComposeInfo.RenderObject = theObj;
            info.ComposeInfo.Width = 2.0;

            DirectoryInfo dbdir = new DirectoryInfo("CorruptCacheDBEntry");
            VisualCacheDirectoryDB db = new VisualCacheDirectoryDB(dbdir);
            db.Save(info);

            /// Truncate the cache files.
            foreach (var f in dbdir.EnumerateFiles())
            {
                using (var writer = f.Create())
                {
                }
            }

            Assert.IsNull(db.FindHit(info.ComposeInfo.Hash), "Wrong number of items found in db");
        }
        
        [TestMethod]
        public void TestWriteTwoItems()
        {
            CacheDBInfo info1 = new CacheDBInfo();
            info1.DZXMLFile = new FileInfo("junk.xml");

            info1.ComposeInfo = new ComposableInfo();
            Uri theObj = new Uri("http://www.nytimes.com");
            info1.ComposeInfo.Hash = theObj.AbsoluteUri.GetHashCode();
            info1.ComposeInfo.Height = 1.0;
            info1.ComposeInfo.MetaData = DateTime.Now;
            info1.ComposeInfo.RenderItemFullType = typeof(t_VisualCacheDirectoryDB).ToString();
            info1.ComposeInfo.RenderObject = theObj;
            info1.ComposeInfo.Width = 2.0;

            CacheDBInfo info2 = new CacheDBInfo();
            info2.DZXMLFile = new FileInfo("bogus.xml");

            info2.ComposeInfo = new ComposableInfo();
            Uri theObj2 = new Uri("http://www.cnn.com");
            info2.ComposeInfo.Hash = theObj2.AbsoluteUri.GetHashCode();
            info2.ComposeInfo.Height = 2.0;
            info2.ComposeInfo.MetaData = DateTime.Now;
            info2.ComposeInfo.RenderItemFullType = typeof(t_VisualCacheDirectoryDB).ToString();
            info2.ComposeInfo.RenderObject = theObj2;
            info2.ComposeInfo.Width = 3.0;

            DirectoryInfo dbdir = new DirectoryInfo("TestWriteTwoItems");
            VisualCacheDirectoryDB db = new VisualCacheDirectoryDB(dbdir);
            db.Save(info1);
            db.Save(info2);

            Assert.IsNotNull(db.FindHit(info1.ComposeInfo.Hash), "Wrong number of items found in db for obj 1");
            Assert.IsNotNull(db.FindHit(info2.ComposeInfo.Hash), "Wrong number of items found in db for obj 2");

            CacheDBInfo infoRet = db.FindHit(info1.ComposeInfo.Hash);
            Assert.AreEqual(1.0, infoRet.ComposeInfo.Height, "Height came back incorrect");

            infoRet = db.FindHit(info2.ComposeInfo.Hash);
            Assert.AreEqual(2.0, infoRet.ComposeInfo.Height, "Height for obj2 came back incorrect");

            Assert.IsNull(db.FindHit(124443), "Shoud find bogus number of items for bogus id");
        }

        [TestMethod]
        public void TestWriteOutSecondTime()
        {
            /// Over write information that is already in the cache - make sure it is replaced,
            /// not added.

            CacheDBInfo info = new CacheDBInfo();
            info.DZXMLFile = new FileInfo("junk.xml");

            info.ComposeInfo = new ComposableInfo();
            Uri theObj = new Uri("http://www.nytimes.com");
            info.ComposeInfo.Hash = theObj.AbsolutePath.GetHashCode();
            info.ComposeInfo.Height = 1.0;
            info.ComposeInfo.MetaData = DateTime.Now;
            info.ComposeInfo.RenderItemFullType = typeof(string).ToString();
            info.ComposeInfo.RenderObject = theObj;
            info.ComposeInfo.Width = 2.0;

            DirectoryInfo dbdir = new DirectoryInfo("TestWriteOutSecondTime");
            VisualCacheDirectoryDB db = new VisualCacheDirectoryDB(dbdir);
            t_TestingLibrary.Utilities.Compose(db);
            db.Save(info);

            info.ComposeInfo.Height = 10.0;
            db.Save(info);

            Assert.IsNotNull(db.FindHit(info.ComposeInfo.Hash), "Wrong number of items found in db");

            CacheDBInfo infoRet = db.FindHit(info.ComposeInfo.Hash);
            Assert.AreEqual(10.0, infoRet.ComposeInfo.Height, "Height came back incorrect");
        }

        [TestMethod]
        public void TestMovingDB()
        {
            /// DB location can be changed while running. Make sure it correctly moves over anything that currently
            /// exists when it does that.

            CacheDBInfo info = new CacheDBInfo();
            info.DZXMLFile = new FileInfo("junk.xml");

            info.ComposeInfo = new ComposableInfo();
            Uri theObj = new Uri("http://www.nytimes.com");
            info.ComposeInfo.Hash = theObj.AbsolutePath.GetHashCode();
            info.ComposeInfo.Height = 1.0;
            info.ComposeInfo.MetaData = DateTime.Now;
            info.ComposeInfo.RenderItemFullType = typeof(t_VisualCacheDirectoryDB).ToString();
            info.ComposeInfo.RenderObject = theObj;
            info.ComposeInfo.Width = 2.0;

            DirectoryInfo dbdir = new DirectoryInfo("TestMovingDB");
            if (dbdir.Exists)
                dbdir.Delete(true);
            VisualCacheDirectoryDB db = new VisualCacheDirectoryDB(dbdir);
            db.Save(info);

            Assert.IsNotNull(db.FindHit(info.ComposeInfo.Hash), "Wrong number of items found in db");
            dbdir.Refresh();
            Assert.IsTrue(dbdir.Exists, "the db dir does not exsit!");

            ///
            /// Now, move it over. It should still work, even though the thing should have moved! And the old one should be gone!
            ///

            DirectoryInfo newdbdir = new DirectoryInfo("TestMovingDB-2nd");
            if (newdbdir.Exists)
                newdbdir.Delete(true);
            newdbdir.Refresh();
            db.DBLocation = newdbdir;
            Assert.IsNotNull(db.FindHit(info.ComposeInfo.Hash), "Wrong number of items found in db");
            Assert.IsTrue(newdbdir.Exists, "The new dbdir should exist now!");
            dbdir.Refresh();
            Assert.IsFalse(dbdir.Exists, "The old db directory should be gone!");

        }
    }
}
